package org.example.basic.util;


import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.function.*;

/**
 *  函数式招式工具类
 *
 * @author songyafei
 */
public class FunctionUtil {

    /**
     * 用来获取一个泛型参数指定类型的对象数据。
     * @param supplier
     * @param <T>
     * @return
     */
    public static <T> T supplier(Supplier<T> supplier){
        return supplier.get();
    }


    /**
     *   Function 使用 获取一组对象中的某个属性，或者 属性增强处理
     * @param list
     * @param f
     * @param <T>
     * @param <R>
     * @return
     */
    public static <T, R> List<R> map(List<T> list,Function<T, R> f) {
        List<R> result = new ArrayList<>();
        for(T s: list){
            result.add(f.apply(s));
        }
        return result;
    }

    /**
     * 过滤集合
     * @param list
     * @param p
     * @param <T>
     * @return List<T>
     */
    public static <T> List<T> filterList(List<T> list, Predicate<T> p){
        List<T> result = new ArrayList<>();
        for(T e: list){
            if(p.test(e)){
                result.add(e);
            }
        }
        return result;
    }

    /**
     *  传入集合对每一个对象做操作
     *   场景分析： 当需要一次对一个对象中的属性做业务单独处理时可以使用
     * @param list
     * @param c
     * @param <T>
     */
    public static <T> void getT(List<T> list,Consumer<T> c){
        list.forEach(i -> c.accept(i));
    }

    /**
     *  传入两个list进行处理后返回一个list
     * @param l1
     * @param l2
     * @param biFunction
     * @param <T>
     * @return T
     */
    public static <T> T calList(List<T> l1, List<T> l2, BiFunction<List<T>,List<T>,List<T>> biFunction){
        return (T) biFunction.apply(l1,l2);
    }

    /**
     * 对比localDate 日期
     * @param d1
     * @param d2
     * @param biPredicate
     * @return boolean
     */
    public static boolean calLocalDate(LocalDate d1, LocalDate d2, BiPredicate<LocalDate,LocalDate> biPredicate){
        return biPredicate.test(d1,d2);
    }

    /**
     * 传入两个同类型的集合做处理
     * @param l1
     * @param l2
     * @param binaryOperator
     * @param <T>
     * @return List<T>
     */
    public static <T> List<T> calList(List<T> l1, List<T> l2, BinaryOperator<List<T>> binaryOperator){
        return  binaryOperator.apply(l1,l2);
    }

    /**
     *  传入两个同类型的字符串做处理
     * @param s1
     * @param s2
     * @param binaryOperator
     * @return String
     */
    public static String calString(String s1,String s2,BinaryOperator<String> binaryOperator){
        return binaryOperator.apply(s1,s2);
    }

    /**
     * 对集合为true 做处理
     * @param list
     * @param booleanSupplier
     * @return Boolean
     */
    public static Boolean calList(List<?> list, BooleanSupplier booleanSupplier){
        return booleanSupplier.getAsBoolean();
    }

    /**
     * 比较两个任意类型做比较
     * @param o1
     * @param o2
     * @param binaryOperator
     * @param <T>
     * @return T
     */
    public static <T>  T calSort(Object o1,Object o2,BinaryOperator<Object> binaryOperator){
        return (T) binaryOperator.apply(o1,o2);
    }



}
